package com.chenfan.ccp.plug.hot;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

public class ClassFileChange extends Thread {


	private String[] paths;
	private Map<String, Long> fileLastLoadTimeMap = new ConcurrentHashMap<>();
	private Function task;

	{
		Runtime.getRuntime().addShutdownHook(new Thread(() -> this.interrupt()));
	}

	public ClassFileChange(Function task, String... paths) {
		this.paths = paths;
		this.task = task;
		Map<String, Long> lastLoadTimes = getLastLoadTimes();
		if (lastLoadTimes != null && !lastLoadTimes.isEmpty()) {
			fileLastLoadTimeMap.putAll(lastLoadTimes);
		}




	}


	public void doTask(Object file) {
		task.apply(file);
	}

	@Override
	public synchronized void start() {
		super.start();
		System.out.println("--启动热部署程序--");
	}

	public List<File> traverseFolder(File file, List<File> files) {

		if (files == null) {
			files = new ArrayList<>();
		}
		if (!file.exists()) {
			return files;
		}

		if (file.isDirectory()) {
			//ignore
			if (!file.getName().equals("META-INF")) {
				for (File childFile : file.listFiles()) {
					traverseFolder(childFile, files);
				}
			}

		} else {
			files.add(file);
		}
		return files;
	}

	@Override
	public void run() {
		while (true) {

			if (isInterrupted()) {
				return;
			}
			synchronized (this) {
				Map<String, Long> lastLoadTimes = getLastLoadTimes();
				boolean onceChangeFlag = true;
				if (lastLoadTimes != null) {
					for (Map.Entry<String, Long> entry : lastLoadTimes.entrySet()) {


						//删除的文件没必要更新
						if (fileLastLoadTimeMap.get(entry.getKey()) == null
							|| !fileLastLoadTimeMap.get(entry.getKey()).equals(entry.getValue())) {
							if (onceChangeFlag) {
								doTask(entry.getKey());
								onceChangeFlag = false;
							}


						}


					}


					//赋值
					fileLastLoadTimeMap = lastLoadTimes;


				}
				try {
					TimeUnit.SECONDS.sleep(3); // 每隔3秒检查一次文件
				} catch (InterruptedException e) {

				}
			}
		}
	}

	/**
	 * 将文件最后修改时间作为最后加载时间
	 *
	 * @return
	 */
	public Map<String, Long> getLastLoadTimes() {
		if (paths == null || paths.length == 0) {
			return new ConcurrentHashMap<>();
		}
		List<File> files;
		Map<String, Long> lastModifiedMap = new HashMap<>();
		for (String path : paths) {
			files = traverseFolder(new File(path).getParentFile(), null);
			for (File file : files) {
				lastModifiedMap.put(file.getAbsolutePath(), file.lastModified());
			}
		}


		return lastModifiedMap;
	}

}
